<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>聊天室</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- CSS -->
  <link rel="stylesheet" href="/css/chat.css">
  <link rel="stylesheet" href="/css/flowbite.min.css">

  <!-- JS -->
  <script src="/lib/marked.min.js"></script>
  <script src="/lib/purify.min.js"></script>
  <script src="/lib/3.4.17.js"></script>
  <script src="/lib/flowbite.min.js"></script>

  <!-- 通知音效 -->
  <audio id="notify-sound" src="/sound/notify.wav" preload="auto"></audio>
</head>
<body class="bg-gray-100 flex justify-center items-center min-h-screen">


<div id="chat-app" class="w-full max-w-6xl bg-white rounded-2xl shadow-lg flex">
  <div id="channel-list" class="w-64 max-h-[600px] p-6 bg-gray-100 border-r rounded-l-2xl flex flex-col overflow-hidden">
    <h3 class="text-2xl font-semibold mb-4 text-gray-800">频道</h3>

    <!-- Vue 动态渲染 -->
    <ul class="space-y-4 flex-1 overflow-y-auto scrollbar-hide">
      <li v-for="ch in channels"
          :key="ch.id"
          @click="selectChannel(ch.id)"
          class="channel-item px-4 py-3 rounded-lg cursor-pointer hover:bg-blue-400 transition-all duration-300 ease-in-out transform hover:scale-105 break-words"
          :class="{
        'bg-blue-600 text-white font-medium': currentChannel && currentChannel.id === ch.id,
        'bg-white text-gray-700': !(currentChannel && currentChannel.id === ch.id)
      }">
        # {{ ch.name }}
      </li>
    </ul>

    <button @click="createChannel"
            class="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-500 transition-all duration-300 ease-in-out transform hover:scale-105">
      + 新建频道
    </button>
  </div>





  <!-- 中间：聊天区 -->
  <div id="chat-area" class="flex-1 flex flex-col h-[600px] border-r">
    <!-- 昵称输入 -->
    <div class="p-3 border-b flex items-center space-x-2 bg-blue-50">
      <label class="text-gray-600 font-medium">昵称:</label>
      <input type="text" id="username"  v-model="username"
             class="p-2 border rounded-lg flex-1 focus:ring focus:ring-blue-300"
             placeholder="请输入昵称" maxlength="10"/>
    </div>

    <!-- 消息展示区 -->
    <div id="chat" ref="chatArea" @scroll="onScroll" class="h-[480px] overflow-y-auto p-4 space-y-4 bg-gray-50 break-words [overflow-wrap:anywhere]">
      <!-- 使用 v-for 渲染消息列表 -->
      <div v-for="(message, index) in messages" :key="index"
           class="flex justify-start space-x-2" :class="{'justify-end': isOwnMessage(message)}">

        <!-- 消息内容 -->
        <div class="bg-blue-500 text-white p-3 rounded-lg max-w-[70%]">
          <!-- 显示发送者和时间 -->
          <div class="flex justify-between text-xs text-gray-200">
            <span class="font-medium">{{ message.sender }}</span>
            <span>{{ message.createDate }}</span>
          </div>
          <!-- 显示消息内容 -->
          <pre class="text-lg text-white preserve-whitespace">
            {{ message.content }}
          </pre>
        </div>
      </div>
    </div>

    <!-- 图片预览弹窗 -->
    <div id="image-overlay" class="hidden fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50">
      <div class="relative">
        <span id="overlay-close" class="absolute top-2 right-2 text-white text-2xl cursor-pointer">&times;</span>
        <img id="overlay-img" src="" alt="预览图片" class="max-h-[80vh] max-w-[90vw] rounded-lg shadow-lg">
      </div>
    </div>

    <!-- 输入消息区 -->
    <div class="p-3 border-t bg-white">
            <textarea id="messageInput" v-model="message"
                      class="w-full p-2 border rounded-lg resize-none focus:ring focus:ring-blue-300"
                      @keydown.enter.prevent="handleSendMessage"
                      placeholder="输入消息..." rows="2">
            </textarea>
      <div class="flex justify-between items-center mt-2">
        <div class="flex items-center space-x-2">
          <input type="file" id="fileInput" class="hidden"/>
          <button class="px-3 py-1 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300">
            上传文件 / 图片
          </button>
        </div>
        <button @click="handleSendMessage"
                class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">发送</button>
      </div>
    </div>
  </div>

  <!-- 右侧：在线用户列表 -->
  <div id="user-list" class="w-60 p-4 bg-gray-50 rounded-r-2xl flex flex-col">
    <h3 class="text-lg font-semibold mb-3 text-gray-700">在线用户</h3>
    <!-- ✅ 动态渲染在线用户列表 -->
    <ul id="online-users" class="space-y-2 overflow-y-auto flex-1">
      <li v-for="user in onlineUsers" :key="user.username" class="flex items-center gap-2 p-2 rounded-lg bg-white shadow-sm">
        <div class="w-2 h-2 bg-green-500 rounded-full"></div>
        <span class="text-gray-800 text-sm">{{ user.username }}</span>
      </li>
    </ul>
  </div>
</div>
<!-- 分离的 JS -->
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script type="module">
  const { createApp, ref, onMounted, nextTick } = Vue;
  import { httpRequest } from '/js/http.js';

  createApp({
    setup() {
      const channels = ref([]);
      const currentChannel = ref(null);
      const message = ref("");
      const messages = ref([]);
      const onlineUsers = ref([]); // ✅ 绑定用户列表
      const username = ref(localStorage.getItem("chat-username") || "");
      const chatArea = ref(null); // 通过 ref 获取 DOM 元素
      const page = ref(1);
      const loading = ref(false);
      let ws = null;

      // 加载列表
      const loadChannels = async () => {
        const data = await httpRequest("/channel/list");
        if (data) channels.value = data;
      };

      // 加载信息
      const onScroll = async () => {
        if (!chatArea.value) return;
        // 接近顶部再加载
        if (chatArea.value.scrollTop <= 20 && !loading.value) {
          loading.value = true;
          page.value++;
          const cuChannel = currentChannel.value; // 直接取到值
          await loadMessages(cuChannel.id);
          loading.value = false;
        }
      };

      // 用户信息
      const loadUserInfo = async () => {
        const user = await httpRequest("/user/getUser");
        if (user) {
          await selectChannel(user.channelId);
        }
      };
      // 是否是当前用户
      const isOwnMessage = (message) => {
        return message.sender === username.value;  // 假设 `username` 是当前用户的用户名
      };

      // 选中频道
      const selectChannel = (channelId) => {
        const channel = channels.value.find(ch => ch.id === channelId);
        if (channel) {
          currentChannel.value = channel;
          // 重新加载消息
          messages.value = [];
          page.value = 1;
          loadMessages(channelId);
        }
      };
      // 加载消息
      const loadMessages = async (channelId) => {
        const data = await httpRequest(`/message/getMessage?channelId=${channelId}&page=${page.value}`);
        if (data && data.length > 0){
          messages.value.unshift(...data);
        }
      };

      // ws 更新列表
      const initWebSocket = () => {
        ws = new WebSocket(`ws://${location.host}/ws/chat`);
        ws.onopen = () => console.log("WebSocket已连接");
        ws.onclose = () => console.log("WebSocket已关闭");
        ws.onerror = (e) => console.error("WebSocket错误:", e);

        ws.onmessage = (event) => {
          const wsMessage = JSON.parse(event.data);
          if(wsMessage.type === "userList"){
            onlineUsers.value.push(...JSON.parse(wsMessage.payload));
          }else{
            let payload = JSON.parse(wsMessage.payload);
            if (Array.isArray(payload)) {
              payload.forEach((msg) => {
                if (msg.content) {
                  messages.value.push(msg);
                }
              });
              scrollToBottom();
            } else {
              console.error("Received data is not an array:", event.data);
            }
          }
        };
      };

      const sendMessage = (text, type = "TEXT", fileName = null) => {
        if (!ws || ws.readyState !== WebSocket.OPEN) {
          console.error("WebSocket未连接");
          return alert("WebSocket未连接");
        }
        if (!username.value) return alert("请输入昵称");

        const msg = {
          type,
          sender: username.value,
          content: text,
          channelId: currentChannel.value.id, // 确保使用 currentChannel 的 id
          fileName,
        };
        console.log("发送消息:", msg); // 在控制台输出消息
        ws.send(JSON.stringify(msg)); // 发送消息
      };

      // 自动滚动到聊天框底部
      const scrollToBottom = () => {
        nextTick(() => {
          // 使用 Vue 的 ref 获取 DOM 元素，而不是直接通过 getElementById
          const chatEl = chatArea.value;
          if (chatEl) {
            chatEl.scrollTop = chatEl.scrollHeight; // 滚动到底部
          } else {
            console.warn("chatArea is null");
          }
        });
      };

      const handleSendMessage = () => {
        const text = message.value.trim();
        if (text) {
          sendMessage(text); // 调用发送消息函数
          message.value = ""; // 清空输入框
        } else {
          alert("请输入有效的消息");
        }
      };

      const createChannel = () => {
        const name = prompt("请输入新频道名称：");
        if (!name || !name.trim()) return;
        const result = httpRequest("/channel/save", {
          method: "POST",
          body: JSON.stringify({ name: name.trim() }),
        });
        if (result) {
          loadChannels();
        }
      }

      onMounted(async () => {
        await loadChannels();
        await loadUserInfo();
        await initWebSocket();
      });

      return {
        channels,
        currentChannel,
        chatArea,
        message,
        messages,
        onlineUsers,
        username,
        onScroll,
        handleSendMessage,
        selectChannel,
        createChannel,
        isOwnMessage
      };
    },
  }).mount("#chat-app");
</script>

</body>
</html>